/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.webservicecomponent.metadata.parameter.serializer;

import com.fasterxml.jackson.databind.JsonNode;
import com.inspur.edp.caf.cef.schema.base.utils.JsonUtil;
import com.inspur.edp.cdp.cdf.component.manager.serializer.CompParameterSerializer;
import com.inspur.edp.component.schema.GspCompParameter;
import com.inspur.edp.webservicecomponent.metadata.parameter.IParameterFetchValueSetting;
import com.inspur.edp.webservicecomponent.metadata.parameter.ParameterFetchValueMode;
import com.inspur.edp.webservicecomponent.metadata.parameter.WebServiceParameter;

import java.text.MessageFormat;

public class WebServiceParameterSerializer extends CompParameterSerializer {

    private static final String FETCH_VALUE_SETTING_JSON_FIELD_NAME = "fetchValueSetting";
    private static final String FETCH_VALUE_MODE_JSON_FIELD_NAME = "fetchValueMode";

    @Override
    protected GspCompParameter createGspCompParam() {
        return new WebServiceParameter();
    }

    @Override
    protected void readExtendInfo(GspCompParameter compParam, JsonNode paramNode) {
        WebServiceParameter wsParameter = (WebServiceParameter) compParam;
        this.readParameterFetchValueMode(wsParameter, paramNode);
    }

    @Override
    protected void writeExtendInfo(GspCompParameter compParam, JsonNode paramNode) {
        WebServiceParameter wsParameter = (WebServiceParameter) compParam;
        this.writeParameterFetchValueMode(wsParameter, paramNode);
    }

    private void readParameterFetchValueMode(WebServiceParameter wsParameter, JsonNode paramNode) {

        String fetchValueModeStr = JsonUtil.getPropValue(paramNode, FETCH_VALUE_MODE_JSON_FIELD_NAME, String.class);
        if (fetchValueModeStr == null) {
            wsParameter.setFetchValueMode(ParameterFetchValueMode.NONE);
            return;
        }
        ParameterFetchValueMode fetchValueMode;

        switch (fetchValueModeStr) {
            case "none":
                fetchValueMode = ParameterFetchValueMode.NONE;
                break;
            case "const":
                fetchValueMode = ParameterFetchValueMode.CONST;
                break;
            case "express":
                fetchValueMode = ParameterFetchValueMode.EXPRESS;
                break;
            case "help":
                fetchValueMode = ParameterFetchValueMode.HELP;
                if (JsonUtil.isExistsProp(paramNode, FETCH_VALUE_MODE_JSON_FIELD_NAME)) {
                    this.readFetchValueSetting(wsParameter, paramNode);
                } else {
                    throw new RuntimeException(MessageFormat.format(
                            "deserialize error:missing \"fetchValueModeSetting\" filed.code:{0},name:{1}",
                            wsParameter.getCode(), wsParameter.getName()));
                }
                break;
            case "enum":
                fetchValueMode = ParameterFetchValueMode.ENUM;
                break;
            default:
                throw new RuntimeException("deserialize error:" + fetchValueModeStr);
        }

        wsParameter.setFetchValueMode(fetchValueMode);
    }

    private void readFetchValueSetting(WebServiceParameter wsParameter, JsonNode paramNode) {
        JsonNode fetchValueSettingNode = JsonUtil.getPropValue(paramNode, FETCH_VALUE_SETTING_JSON_FIELD_NAME, JsonNode.class);
        if (fetchValueSettingNode != null) {
            IParameterFetchValueSetting fetchValueSetting = ParameterFetchValueSettingSerializer.deserialize(fetchValueSettingNode);
            wsParameter.setFetchValueSetting(fetchValueSetting);
        }
    }

    private void writeParameterFetchValueMode(WebServiceParameter wsParameter, JsonNode paramNode) {

        ParameterFetchValueMode fetchValueMode = wsParameter.getFetchValueMode();
        if (fetchValueMode == null) {
            return;
        }

        String fetchValueModeStr;
        switch (fetchValueMode) {
            case NONE:
                fetchValueModeStr = "none";
                break;
            case CONST:
                fetchValueModeStr = "const";
                break;
            case EXPRESS:
                fetchValueModeStr = "express";
                break;
            case HELP:
                fetchValueModeStr = "help";
                if (wsParameter.getFetchValueSetting() != null) {
                    this.writeFetchValueSetting(wsParameter, paramNode);
                } else {
                    throw new RuntimeException(MessageFormat.format(
                            "serialize error:missing \"fetchValueModeSetting\" filed.code:{0},name:{1}",
                            wsParameter.getCode(), wsParameter.getName()));
                }
                break;
            case ENUM:
                fetchValueModeStr = "enum";
                break;
            default:
                throw new RuntimeException("deserialize error:" + fetchValueMode);
        }
        JsonUtil.setPropValue(paramNode, FETCH_VALUE_MODE_JSON_FIELD_NAME, fetchValueModeStr);
    }

    private void writeFetchValueSetting(WebServiceParameter wsParameter, JsonNode paramNode) {
        IParameterFetchValueSetting fetchValueSetting = wsParameter.getFetchValueSetting();
        if (fetchValueSetting != null) {
            JsonNode valueSettingNode = ParameterFetchValueSettingSerializer.serialize(fetchValueSetting);
            JsonUtil.setPropValue(paramNode, FETCH_VALUE_SETTING_JSON_FIELD_NAME, valueSettingNode);
        }
    }
}
